package pers.wchen.mybatis.generate.tag;

import pers.wchen.mybatis.generate.model.DataComposeVO;
import pers.wchen.mybatis.generate.model.DatabaseTablePropertyVO;
import pers.wchen.mybatis.generate.model.FileInfoVO;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @作者： wchen
 * @描述：
 * @创建时间： 2018/2/13 16:50
 * @版本：Copyright 2018, Inc. All Rights Reserved.
 * @修改信息：
 */
public abstract class AbsTagManager implements BaseTagManager {
    //表字段的相关信息
    public List<DatabaseTablePropertyVO> databaseTablePropertyVOS;
    //表注释
    public String tableComponent;
    //文件输出相关信息
    public Map<String, FileInfoVO> fileInfoMap;
    //创建的文件标识
    public String buildFileTag;
    //表名
    public String tableName;

    public AbsTagManager(DataComposeVO dataComposeVO, String tableName, String buildFileTag){
        this.tableComponent = dataComposeVO.getTableComponent();
        this.databaseTablePropertyVOS = dataComposeVO.getDatabaseTablePropertyVOS();
        this.fileInfoMap = dataComposeVO.getFileInfoMap();
        this.buildFileTag = buildFileTag;
        this.tableName = tableName;
    }


    /**
     *  @描述: 模板标签替换
     *  @参数： [templateStr]
     *  @返回值： java.lang.String
     *  @创建人: wchen
     *  @创建时间: 2018/2/13
     *  @修改人和其它信息:
     */
    public String dealTemplateTag(String templateStr) {

        String replaceParamStr = replaceFileParam(templateStr);
        String replaceLoopStockStr = dealLoopStock(replaceParamStr);
//        System.err.println("replaceLoopStock11：===========");
//        System.out.println(replaceLoopStockStr);
        return replaceLoopStockStr;
    }

    
    /**
     *  @描述: 替换头部
     *  @参数：
     *  @返回值： 
     *  @创建人: wchen
     *  @创建时间: 2018/2/13
     *  @修改人和其它信息: 
     */
    public abstract String replaceFileParam(String templateStr);


    /**
     *  @描述: 循环标签处理
     *  @参数：
     *  @返回值： 
     *  @创建人: wchen
     *  @创建时间: 2018/2/13
     *  @修改人和其它信息: 
     */
    public abstract String replaceLoopStock(String dealLine, Set<String> exIncludeFields);





    /**
     *  @描述: 正则匹配处理for循环
     *  @参数： [sbf]
     *  @返回值： java.lang.String
     *  @创建人: wchen
     *  @创建时间: 2018/2/13
     *  @修改人和其它信息:
     */
    public String dealLoopStock(String sbf){
//        Pattern pattern = Pattern.compile("[\\s]*<@loop.for[\\_\\{\\}\\,\\w]*>([\\'\\+\\(\\)\\;\\w\\*\\<\\>\\=\\&\\\"\\.\\{\\}\\/\\s\\r\\n\\!\\'\\,\\#]+)<@loop.for_end>");
        Pattern pattern = Pattern.compile("[\\s]*<@loop.for[\\_\\{\\}\\,\\w]*>([\\u4e00-\\u9fa5\\-\\?\\$\\'\\+\\(\\)\\;\\w\\*\\<\\>\\=\\&\\\"\\.\\{\\}\\/\\s\\r\\n\\!\\'\\,\\#]+)<@loop.for_end>");
        Matcher matcher = pattern.matcher(sbf);
        StringBuffer resultSbf = new StringBuffer();
        while (matcher.find()){
            //获取loop块
            String matcherLoopStock = matcher.group();
            Set<String> exIncludeFields = new HashSet<String>();
            //移除loop标签
            String dealLine = removeLoopTag(matcherLoopStock, exIncludeFields);
            //内容替换(开头加回车)
            String replaceLoopStock = "\n" + replaceLoopStock(dealLine, exIncludeFields);
//            System.out.println(replaceLoopStock);
            matcher.appendReplacement(resultSbf,  replaceLoopStock);
        }
        matcher.appendTail(resultSbf);
        return finalDeal(resultSbf.toString());
    }


    /**
     *  @描述: 字符串转义特殊处理
     *  @参数： [templateStr]
     *  @返回值： java.lang.String
     *  @创建人: wchen
     *  @创建时间: 2018/2/17
     *  @修改人和其它信息:
     */
    public String finalDeal(String templateStr){
        return templateStr;
    }

    /**
     *
     * @描述： 正则匹配去除for定义
     * @名称： matchLoop
     * @入参： [loopLine]
     * @出参： java.lang.String
     * @修改信息： 创建：wchen 2018/2/5
     */
    private String removeLoopTag(String loopLine, Set<String> notIncludeSet){
        StringBuffer sbf = new StringBuffer();
        //去除回车字符
//        Pattern pattern = Pattern.compile("[\\n\\r]");
//        Matcher matcher = pattern.matcher(loopLine);
//        String strWithoutEnter = matcher.replaceAll("");

        //去除loop.for标签
        Pattern pattern = Pattern.compile("[\\n\\r\\s]*<@loop.for[\\_\\{\\}\\,\\w]*>[\\n\\r]*");
        Matcher matcher = pattern.matcher(loopLine);
        //获取不处理的字段
        if (matcher.find()){
            String matcherLine = matcher.group();
            Pattern filePattern = Pattern.compile("\\{[\\w\\,]+\\}");
            Matcher fileMatcher = filePattern.matcher(matcherLine);
            if(fileMatcher.find()){
                matcherLine = fileMatcher.group().trim();
                String[] exFields = matcherLine.substring(1, matcherLine.length() - 1).split(",");
                for(String field : exFields){
                    notIncludeSet.add(field);
                }
            }
        }
        String strWithoutSpace = matcher.replaceAll("");
        return strWithoutSpace;
    }







    /**
     *
     * @描述： &{param.jdbcType}替换
     * @名称： replaceVoFieldName
     * @入参： [line, objStr]
     * @出参： java.lang.String
     * @修改信息： 创建：wchen 2018/2/5
     */
    public String replaceJdbcType(String line, String objStr){
        return replaceStr(line, "&{param.jdbcType}", objStr);
    }

    /**
     *
     * @描述： &{param.tableFieldName}替换
     * @名称： replaceVoFieldName
     * @入参： [line, objStr]
     * @出参： java.lang.String
     * @修改信息： 创建：wchen 2018/2/5
     */
    public String replaceVoFieldName(String line, String objStr){
        return replaceStr(line, "&{param.voFieldName}", objStr);
    }


    /**
     *
     * @描述： &{param.tableFieldName}替换
     * @名称： replaceVoFieldName
     * @入参： [line, objStr]
     * @出参： java.lang.String
     * @修改信息： 创建：wchen 2018/2/5
     */
    public String replaceTableFieldName(String line, String objStr){
        return replaceStr(line, "&{param.tableFieldName}", objStr);
    }


    /**
     *
     * @描述： 字符串替换
     * @名称： replaceStr
     * @入参： [line, targetStr, objStr]
     * @出参： java.lang.String
     * @修改信息： 创建：wchen 2018/2/5
     */
    private String replaceStr(String line, String targetStr, String objStr){
        return line.replace(targetStr, objStr);
    }


}
